//
// Created by 17775 on 2024/6/25.
//

#include <iostream>
#include <cmath>
#include <QTimer>
#include "livemode_2d_view.h"
#include "ui_LiveMode_2D_View.h"
#include "../utils/LogManager.h"
#include "../RayCi/LiveMode.h"  // 包含AOI结构体定义

#ifndef M_PI
#define M_PI 3.14159265358979323846
#endif
#define MAX_AOIITEM 16

LiveMode_2D_View::LiveMode_2D_View(LiveMode_2D_View_Settings *settings, QWidget *parent) :
        QDockWidget(parent), _2DImagePlot(new QCustomPlot(this)), ui(new Ui::LiveMode_2D_View),
        m_settings(settings) {
    ellipses.resize(MAX_AOIITEM, nullptr);
    aoiLabels.resize(MAX_AOIITEM, nullptr);
    setAllowedAreas(Qt::NoDockWidgetArea);
    ellipseParams.resize(MAX_AOIITEM);
    setWindowTitle("LiveMode:Options");
    setWindowFlags(Qt::Window | Qt::WindowTitleHint | Qt::WindowCloseButtonHint| Qt::WindowMinimizeButtonHint
                   | Qt::WindowMaximizeButtonHint);
    ui->setupUi(this);
    //在名为 "main" 的图层之上创建一个名为 "crossLayer" 的新图层。
    _2DImagePlot->addLayer("crossLayer", _2DImagePlot->layer("main"), QCustomPlot::limAbove);
    m_lutWidget = new CommonLutWidget();
    set2DMapArea();
    initCoordinateSystem();
    m_lutWidget->initLUTWidget(ui->LUT_Widget);

    connect(ui->btnMeasurement, &QPushButton::clicked, this, &LiveMode_2D_View::btnMeasurement_Click);
    connect(ui->btnSnapshot, &QPushButton::clicked, this, &LiveMode_2D_View::btnSnapshot_Click);
    connect(ui->btnBeamResults, &QPushButton::clicked, this, &LiveMode_2D_View::btnBeamResults_Click);
    // 连接菜单项点击信号
    m_pAOIMenu = new QMenu(this);
    connect(m_pAOIMenu, &QMenu::triggered, this, &LiveMode_2D_View::onAOIActionTriggered);
    //菜单初始化所有的菜单项
    for (int i = 0; i < MAX_AOIITEM; ++i) {
        QString actionName = "AOI" + QString::number(i+1);
        QAction* action = new QAction(actionName, this);
        action->setCheckable(true); // 支持多选
        action->setData(i); // 存储AOI索引
        // 设置第一个AOI为主AOI（默认加粗）
        if (i == 0) {
            QFont boldFont = action->font();
            boldFont.setBold(true);
            action->setFont(boldFont);
            action->setText(actionName + " ★"); // 添加主标记
        }
        m_pAOIMenu->addAction(action);
        m_aoiActions.append(action);
    }
    ui->btnAOISelection->setText("AOI Selection ▶");
    connect(ui->btnAOISelection, &QPushButton::clicked, this, &LiveMode_2D_View::btnAOISelection_Click);

    // 初始化AOI状态
    initAOIStates();
    connect(ui->btnAdjustCS, &QPushButton::clicked, this, &LiveMode_2D_View::btnAdjustCS_Click);
    connect(ui->btn3D_View, &QPushButton::clicked, this, &LiveMode_2D_View::btn3D_View_Click);
    connect(ui->btnCross_Section, &QPushButton::clicked, this, &LiveMode_2D_View::btnCross_Section_Click);
    connect(ui->btnCentroid, &QPushButton::clicked, this, &LiveMode_2D_View::btnCentroid_Click);
    connect(ui->btnPower_Profile, &QPushButton::clicked, this, &LiveMode_2D_View::btnPower_Profile_Click);
    connect(ui->btnHistogram, &QPushButton::clicked, this, &LiveMode_2D_View::btnHistogram_Click);
    connect(ui->btn_BeamProfiler_Dynamic, &QPushButton::clicked, this, &LiveMode_2D_View::btn_BeamProfiler_Dynamic_Click);
    connect(_2DImagePlot, &QCustomPlot::mousePress, this, &LiveMode_2D_View::onMousePress);
    connect(_2DImagePlot, &QCustomPlot::mouseMove, this, &LiveMode_2D_View::onMouseMove);
    connect(_2DImagePlot, &QCustomPlot::mouseRelease, this, &LiveMode_2D_View::onMouseRelease);
    connect(ui->cBox_Auto, &QCheckBox::clicked, this, [=] () {
        emit setAutoContrast(ui->cBox_Auto->isChecked());
    });

    if (m_settings) {
        connect(m_settings, &LiveMode_2D_View_Settings::Show_Or_Hide_Aoi, this, &LiveMode_2D_View::handleShowOrHideAoi);
        connect(m_settings, &LiveMode_2D_View_Settings::mainAOIChanged, this, &LiveMode_2D_View::handleMainAOIChanged);
        connect(m_settings, &LiveMode_2D_View_Settings::setVisualization, this, [this](bool checked) {

       if (checked&&vArrow->start->coords().x() == 0 && vArrow->start->coords().y() == 0 &&
           vArrow->end->coords().x() == 1 && vArrow->end->coords().y() == 1 &&
           hArrow->start->coords().x() == 0 && hArrow->start->coords().y() == 0 &&
           hArrow->end->coords().x() == 1 && hArrow->end->coords().y() == 1) {

           double plotWidth = _2DImagePlot->width();
           double plotHeight = _2DImagePlot->height();

           vArrow->start->setCoords(plotWidth, 0);
           vArrow->end->setCoords(plotWidth, plotHeight * 1.9);

           hArrow->start->setCoords(0, plotHeight);
           hArrow->end->setCoords(plotWidth * 1.9 - 35, plotHeight);

           _2DImagePlot->replot(QCustomPlot::rpQueuedReplot);
           }
           vArrow->setVisible(checked);
           hArrow->setVisible(checked);

           isVisible = checked;
           _2DImagePlot->replot(QCustomPlot::rpQueuedReplot);
   });
        connect(m_settings, &LiveMode_2D_View_Settings::Coordinate_Arrow_Convert, this, [this](int index) {
        switch (index) {
            case 0:
            case 1: {
                QPointF hStart = hArrow->start->coords();
                QPointF hEnd = hArrow->end->coords();
                hArrow->start->setCoords(hEnd);
                hArrow->end->setCoords(hStart);
                break;
            }
            case 2:
            case 3: {
                QPointF vStart = vArrow->start->coords();
                QPointF vEnd = vArrow->end->coords();
                vArrow->start->setCoords(vEnd);
                vArrow->end->setCoords(vStart);
                break;
            }
        }

        _2DImagePlot->replot(QCustomPlot::rpQueuedReplot);
    });
    }

}

int LiveMode_2D_View::nSizeX = 0;
int LiveMode_2D_View::nSizeY = 0;


void LiveMode_2D_View::onMousePress(const QMouseEvent *event)  {
    double cPos = 0;
    double mPos = 0;
    auto dxPos = _2DImagePlot->xAxis->pixelToCoord(event->pos().x());
    auto dyPos = _2DImagePlot->yAxis->pixelToCoord(event->pos().y());
    QPointF mousePos(dxPos, dyPos);
    switch (crossSectionType) {
        case 0: {
            cPos = crossSectionLine->start->coords().y();
            mPos = dyPos;
            if (event->button() == Qt::LeftButton && fabs(cPos - mPos) < 5) {
                isDraggingXCrossSectionLine = true;
            }
            break;
        }
        case 1: {
            cPos = crossSectionLine->start->coords().x();
            mPos = dxPos;
            if (event->button() == Qt::LeftButton && fabs(cPos - mPos) < 5) {
                isDraggingXCrossSectionLine = true;
            }
            break;
        }
        case 2: {
//            auto start = crossSectionLine->start->coords();
//            auto end = crossSectionLine->end->coords();
//            double distance = calculateDistanceToCrossSectionLine(mousePos, start, end);
//            if(distance < 5) {
//                crossIsRotating = true;
//            }
//            break;
        }
        case 3: {
            double distToStart = calculateTwoPointDistance(mousePos, crossSectionLine->start->coords());
            double distToEnd = calculateTwoPointDistance(mousePos, crossSectionLine->end->coords());
            if (distToStart < 5) {
                crossStartEnding = true;
                draggingEndpoint = StartPoint;
                dragStartPos = crossSectionLine->start->coords();
            }
            else if (distToEnd < threshold) {
                crossStartEnding = true;
                draggingEndpoint = EndPoint;
                dragStartPos = crossSectionLine->end->coords();
            }
            else {
                draggingEndpoint = None;
            }
            break;
        }
        case 4: {
            if (event->button() == Qt::LeftButton && calculateDistanceToEllipseBoundary(crossSectionCircle, mousePos) <= 25) {
                crossCircleIsMoving = true;
                crossSectionCircle->setSelected(true);
            }
            break;
        }
    }

    // 检查是否点击了任何椭圆曲线
    if (event->button() == Qt::LeftButton) {
        // 先检查所有椭圆
        for (int i = 0; i < ellipses.size(); ++i) {
            if (ellipses[i] && ellipses[i]->visible()) {
                EllipseParams params = getEllipseParams(i);
                if (calculateDistanceToCurveBoundary(ellipses[i], mousePos, params.center, params.major, params.minor, params.azimuthAngle) <= 25) {
                // 记录当前主AOI索引，以便操作完成后恢复
                m_previousMainAOIIndex = m_mainAOIIndex;
                // 如果点击的不是当前主AOI，则临时设置为主AOI
                if (m_mainAOIIndex != i) {
                    setMainAOI(i);
                    qDebug() << "临时将椭圆" << i << "设置为主AOI";
                }
                // 记录当前操作的椭圆
                m_currentOperatingEllipse = ellipses[i];
                    m_currentOperatingEllipseIndex = i;
                    QPen selectedPen = m_currentOperatingEllipse->pen();
                    selectedPen.setColor(Qt::red);
                    selectedPen.setWidth(2);
                    m_currentOperatingEllipse->setPen(selectedPen);

                // 设置拖动开始时的光标形状
                Qt::CursorShape initialCursorShape = getCursorShapeForPosition(mousePos, params);
                setCursor(initialCursorShape);

                // 记录鼠标位置
                mouseIsMoving = true;
                lastMousePos = mousePos;
                // 找到了要操作的椭圆，退出循环
                break;
                }
            }
        }
    }
    if (event->button() == Qt::RightButton) {
        if(m_contextMenu == nullptr) {
            m_contextMenu = new QMenu(this);
            auto m_rescaleAction = new QAction("Zoom to View", this);
            auto m_settingAction = new QAction("Settings", this);
            m_contextMenu->addAction(m_rescaleAction);
            m_contextMenu->addAction(m_settingAction);
            connect(m_rescaleAction, &QAction::triggered, this, [=]() {
                  _2DImagePlot->rescaleAxes(true);
            });
            connect(m_settingAction, &QAction::triggered, this, [=]() {
                emit show2DViewSetting();
            });
        }
        m_contextMenu->exec(QCursor::pos());
    }
}

void LiveMode_2D_View::onMouseMove(const QMouseEvent *event){
    double cPos = 0;
    double mPos = 0;
    auto currentMouseX = _2DImagePlot->xAxis->pixelToCoord(event->pos().x());
    auto currentMouseY = _2DImagePlot->yAxis->pixelToCoord(event->pos().y());
    QPointF currentMousePos(currentMouseX, currentMouseY);

    // 标记是否需要设置截面线光标
    bool setCrossSectionCursor = false;
    Qt::CursorShape crossSectionCursorShape = Qt::ArrowCursor;

    switch (crossSectionType) {
        case 0: {
            cPos = crossSectionLine->start->coords().y();
            mPos = _2DImagePlot->yAxis->pixelToCoord(event->pos().y());
            if (fabs(cPos - mPos) < 5) {
                setCrossSectionCursor = true;
                crossSectionCursorShape = Qt::SizeVerCursor;
            }
            if (isDraggingXCrossSectionLine && event->buttons() & Qt::LeftButton)
            {
                crossSectionLine->start->setCoords(0, mPos);
                crossSectionLine->end->setCoords(nSizeX, mPos);
                crossSectionText->position->setCoords(510, mPos);
                crossSectionText->setText(QString("Y = %1").arg(mPos, 0, 'f', 2));
            }
            break;
        }
        case 1: {
            cPos = crossSectionLine->start->coords().x();
            mPos = _2DImagePlot->xAxis->pixelToCoord(event->pos().x());
            if (fabs(cPos - mPos) < 5) {
                setCrossSectionCursor = true;
                crossSectionCursorShape = Qt::SizeHorCursor;
            }
            if (isDraggingXCrossSectionLine && event->buttons() & Qt::LeftButton)
            {
                crossSectionLine->start->setCoords(mPos, 0);
                crossSectionLine->end->setCoords(mPos, nSizeY);
                crossSectionText->position->setCoords(mPos, 510);
                crossSectionText->setText(QString("Y = %1").arg(mPos, 0, 'f', 2));
            }
            break;
        }
        case 2 : {
//            if (crossIsRotating) {
//                double currentAngle = std::atan2(currentMouseY - crossCenter.y(), currentMouseX - crossCenter.x());
//                double angleDiff = currentAngle - lastAngle;
//                QPointF newStart = rotatePoint(crossSectionLine->start->coords(), angleDiff);
//                QPointF newEnd = rotatePoint(crossSectionLine->end->coords(), angleDiff);
//                crossSectionLine->start->setCoords(newStart);
//                crossSectionLine->end->setCoords(newEnd);
//                lastAngle = currentAngle;
//            }

//            if (crossIsRotating) {
//                QPointF center(1000, 1000); // 旋转中心点坐标
//                QPointF clickPoint(currentMouseX, currentMouseY); // 点击点坐标
//                QLineF line(center, clickPoint); // 通过旋转中心和点击点形成直线
//                angle = line.angle(); // 获取该直线与x轴正方向的夹角
//            }
//            break;
        }
        case 3 : {
            if (draggingEndpoint != None && crossStartEnding) {
                QPointF newPos(currentMouseX, currentMouseY);
                draggingEndpoint == StartPoint ? crossSectionLine->start->setCoords(newPos) : crossSectionLine->end->setCoords(newPos);
            }
            break;
        }
        case 4 : {
            if (crossCircleIsMoving) {
                const QPointF center(preX, preY);
                auto distance = calculateTwoPointDistance(currentMousePos, center);
                crossSectionCircle->topLeft->setCoords(preX - distance, preY - distance);
                crossSectionCircle->bottomRight->setCoords(preX + distance, preY + distance);
                preRadius = distance;
            }
            break;
        }
    }


    // 优先处理椭圆拖动
    if (mouseIsMoving && m_currentOperatingEllipse && m_currentOperatingEllipseIndex >= 0) {
        const QPointF delta = currentMousePos - lastMousePos;
        EllipseParams params = getEllipseParams(m_currentOperatingEllipseIndex);

        // 计算当前椭圆的边界
        double left = params.center.x() - params.major/2.0;
        double right = params.center.x() + params.major/2.0;
        double top = params.center.y() - params.minor/2.0;
        double bottom = params.center.y() + params.minor/2.0;

        // 判断鼠标最初点击的位置，只移动相应的边界
        double initialMouseX = lastMousePos.x();
        double initialMouseY = lastMousePos.y();

        // 水平方向：只调整鼠标初始点击位置所在的边
        if (initialMouseX > params.center.x()) {
            // 鼠标在右半边，只移动右边界
            right += delta.x();
        } else {
            // 鼠标在左半边，只移动左边界
            left += delta.x();
        }

        // 垂直方向：只调整鼠标初始点击位置所在的边
        if (initialMouseY > params.center.y()) {
            // 鼠标在下半边，只移动下边界
            bottom += delta.y();
        } else {
            // 鼠标在上半边，只移动上边界
            top += delta.y();
        }

        // 从新的边界计算椭圆参数
        params.center.setX((left + right) / 2.0);
        params.center.setY((top + bottom) / 2.0);
        params.major = std::abs(right - left);
        params.minor = std::abs(bottom - top);

        // 确保最小尺寸
        params.major = std::max(10.0, params.major);
        params.minor = std::max(10.0, params.minor);

        // 更新椭圆参数和显示
        setEllipseParams(m_currentOperatingEllipseIndex, params);
        updateEllipseCurve(m_currentOperatingEllipse, params.center, params.major, params.minor, params.azimuthAngle);

        // 在拖动过程中设置正确的光标形状
        Qt::CursorShape dragCursorShape = getCursorShapeForPosition(currentMousePos, params);
        setCursor(dragCursorShape);

        // 更新标签位置
        updateAOILabels();
        lastMousePos = currentMousePos;
        getFloatThreadThreadRunning.store(false, std::memory_order_release);
    }
    else {
        // 检查鼠标是否靠近任何椭圆的边缘（椭圆检测优先级高于截面线）
        bool nearAnyEllipseEdge = false;
        Qt::CursorShape cursorShape = Qt::ArrowCursor;

        // 首先检查主AOI椭圆，确保索引有效
        if (m_mainAOIIndex >= 0 && m_mainAOIIndex < ellipses.size() && ellipses[m_mainAOIIndex]) {
            EllipseParams params = getEllipseParams(m_mainAOIIndex);
            if (const double distance = calculateDistanceToCurveBoundary(ellipses[m_mainAOIIndex], currentMousePos,
                                                                        params.center, params.major, params.minor, params.azimuthAngle); distance <= 15) {
                // 根据鼠标位置决定光标形状
                cursorShape = getCursorShapeForPosition(currentMousePos, params);
                nearEllipseEdge = true;
                nearAnyEllipseEdge = true;
            }
        }
        // 如果不靠近主AOI椭圆，检查其他选中的AOI椭圆
        if (!nearAnyEllipseEdge) {
            for (int i = 0; i < ellipses.size(); ++i) {
                if (i != m_mainAOIIndex && i < m_aoiStates.size() && ellipses[i] && m_aoiStates[i]) {
                    EllipseParams params = getEllipseParams(i);
                    if (const double distance = calculateDistanceToCurveBoundary(ellipses[i], currentMousePos,
                                                                                params.center, params.major, params.minor, params.azimuthAngle); distance <= 15) {
                        // 根据鼠标位置决定光标形状
                        cursorShape = getCursorShapeForPosition(currentMousePos, params);
                        nearEllipseEdge = true;
                        nearAnyEllipseEdge = true;
                        break;
                    }
                }
            }
        }

        // 只有在不靠近椭圆边缘时，才考虑截面线光标
        if (!nearAnyEllipseEdge && setCrossSectionCursor) {
            cursorShape = crossSectionCursorShape;
        }

        // 统一设置光标（使用setCursor而不是_2DImagePlot->setCursor以保持一致性）
        setCursor(cursorShape);
        nearEllipseEdge = nearAnyEllipseEdge;
    }
    _2DImagePlot->replot(QCustomPlot::rpQueuedReplot);
}

void LiveMode_2D_View::onMouseRelease(const QMouseEvent *event){
    if (event->button() == Qt::LeftButton && isDraggingXCrossSectionLine) {
        isDraggingXCrossSectionLine = false;
        double pos = 0;
        switch (crossSectionType) {
            case 0: {
                pos = crossSectionLine->start->coords().y();
                preYPos = pos;
                break;
            }
            case 1: {
                pos = crossSectionLine->start->coords().x();
                preXPos = pos;
                break;
            }
        }
        emit setCrossPos(pos);


    }

    if (event->button() == Qt::LeftButton && crossCircleIsMoving) {
        crossCircleIsMoving = false;
        updateCircle(preX, preY, preRadius);
    }

    if (event->button() == Qt::LeftButton && mouseIsMoving && m_currentOperatingEllipse) {
        mouseIsMoving = false;

        if (m_currentOperatingEllipseIndex >= 0) {
            EllipseParams params = getEllipseParams(m_currentOperatingEllipseIndex);
            const double x = params.center.x();
            const double y = params.center.y();
            const double radiusX = params.major / 2.0;
            const double radiusY = params.minor / 2.0;
            const double eAngle = params.azimuthAngle;

        // 如果操作的是主AOI椭圆，发送更新信号
            if (m_currentOperatingEllipseIndex == m_mainAOIIndex) {
                qDebug()<<"当前的主AOI索引是"<<m_mainAOIIndex;
                emit updateEllipse(x, y, radiusX * 2, radiusY * 2, eAngle, m_mainAOIIndex);
            }
        }

        // 恢复原来的主AOI
        if (m_previousMainAOIIndex != -1 && m_previousMainAOIIndex != m_mainAOIIndex) {
            setMainAOI(m_previousMainAOIIndex);
            qDebug()<<"恢复原来的主AOI"<<m_previousMainAOIIndex;
        }

        // 恢复椭圆的原始样式
        if (m_currentOperatingEllipseIndex >= 0) {
            QPen normalPen(Qt::DashLine);
            if (m_currentOperatingEllipseIndex == 0) {
                normalPen.setColor(Qt::white); // 主AOI为白色
            } else {
                QColor color = m_settings->getColorForIndex(m_currentOperatingEllipseIndex+1);
                normalPen.setColor(color);
            }
            normalPen.setWidth(1);
            m_currentOperatingEllipse->setPen(normalPen);
        }

        // 恢复正常的光标形状
        setCursor(Qt::ArrowCursor);

        m_currentOperatingEllipse = nullptr;
        m_currentOperatingEllipseIndex = -1;
        m_previousMainAOIIndex = -1; // 重置之前的主AOI索引
    }

    if (event->button() == Qt::LeftButton && crossStartEnding) {
        auto dX1 = crossSectionLine->start->coords().x();
        auto dY1 = crossSectionLine->start->coords().y();
        auto dX2 = crossSectionLine->end->coords().x();
        auto dY2 = crossSectionLine->end->coords().y();
        emit updateArbitrary(dX1, dY1, dX2, dY2);
        crossStartEnding = false;
    }
}

double LiveMode_2D_View::calculateDistanceToEllipseBoundary(QCPItemEllipse *_ellipse, const QPointF &mousePos) {
    if(!_ellipse) return 0;
    const QPointF center((_ellipse->topLeft->coords().x() + _ellipse->bottomRight->coords().x()) / 2.0,
                         (_ellipse->topLeft->coords().y() + _ellipse->bottomRight->coords().y()) / 2.0);

    const double radiusX = std::abs(_ellipse->bottomRight->coords().x() - _ellipse->topLeft->coords().x()) / 2.0;
    const double radiusY = std::abs(_ellipse->bottomRight->coords().y() - _ellipse->topLeft->coords().y()) / 2.0;

    const double dx = mousePos.x() - center.x();
    const double dy = mousePos.y() - center.y();

    const double angle = std::atan2(dy * radiusX, dx * radiusY);
    const double xOnEllipse = radiusX * std::cos(angle);
    const double yOnEllipse = radiusY * std::sin(angle);

    const double distance = std::hypot(dx - xOnEllipse, dy - yOnEllipse);
    return distance;
}

double LiveMode_2D_View::calculateTwoPointDistance(const QPointF &p1, const QPointF &p2) {
    double dx = p1.x() - p2.x();
    double dy = p1.y() - p2.y();
    return std::sqrt(dx * dx + dy * dy);
}

double LiveMode_2D_View::calculateDistanceToCrossSectionLine(const QPointF &p, const QPointF &a, const QPointF &b) {
    double A = p.x() - a.x();
    double B = p.y() - a.y();
    double C = b.x() - a.x();
    double D = b.y() - a.y();

    double dot = A * C + B * D;
    double len_sq = C * C + D * D;
    double param = -1;
    if (len_sq != 0)
        param = dot / len_sq;

    double xx, yy;

    if (param < 0)
    {
        xx = a.x();
        yy = a.y();
    }
    else if (param > 1)
    {
        xx = b.x();
        yy = b.y();
    }
    else
    {
        xx = a.x() + param * C;
        yy = a.y() + param * D;
    }

    double dx = p.x() - xx;
    double dy = p.y() - yy;
    return std::sqrt(dx * dx + dy * dy);
}

QPointF LiveMode_2D_View::rotatePoint(const QPointF &point, double angle)
{
    double cosA = std::cos(angle);
    double sinA = std::sin(angle);
    return {point.x() * cosA - point.y() * sinA, point.x() * sinA + point.y() * cosA};
}

void LiveMode_2D_View::btnAdjustCS_Click(){


    vArrow->start->setCoords(640, 0);
    vArrow->end->setCoords(640, 1024);
    hArrow->start->setCoords(0, 512);
    hArrow->end->setCoords(1280, 512);

    if (!isVisible) {
        vArrow->setVisible(true);
        hArrow->setVisible(true);
        isVisible = true;
    } else {
        vArrow->setVisible(false);
        hArrow->setVisible(false);
        isVisible = false;
    }
    m_settings->showCoordSyem(isVisible);
    _2DImagePlot->replot(QCustomPlot::rpQueuedReplot);
}

void LiveMode_2D_View::updateCoords(bool isXImageOrAOI, int index) {
    double plotWidth = 640;
    double plotHeight = 512;
    double AllWidth=1280;
    double AllHeight=1024;
    if(isXImageOrAOI) {
        if(index == 0) {
            if(xIndex == 0) {
                vArrow->start->setCoords(0, 0);
                vArrow->end->setCoords(0, AllHeight);
            }
            else if(xIndex == 1) {
                vArrow->start->setCoords(plotWidth, 0);
                vArrow->end->setCoords(plotWidth, AllHeight);
            }
            else {
                vArrow->start->setCoords(AllWidth, 0);
                vArrow->end->setCoords(AllWidth, AllHeight);
            }
            bXImageOrAOI = true;
        }
        else {
            EllipseParams params = getEllipseParams(0);
            if(xIndex == 0) {
                prevArrowStartX = params.center.x() - params.major/2;
                vArrow->start->setCoords(prevArrowStartX, 0);
                vArrow->end->setCoords(prevArrowStartX, AllHeight);
            }
            else if(xIndex == 1) {
                prevArrowStartX = params.center.x();
                vArrow->start->setCoords(prevArrowStartX, 0);
                vArrow->end->setCoords(prevArrowStartX, AllHeight);
            }
            else {
                prevArrowStartX = params.center.x() + params.major/2;
                vArrow->start->setCoords(prevArrowStartX, 0);
                vArrow->end->setCoords(prevArrowStartX, AllHeight);
            }
            bXImageOrAOI = false;
        }
    }
    else {
        if(index == 0) {
            if(yIndex == 0) {
                hArrow->start->setCoords(0, 0);
                hArrow->end->setCoords(AllWidth, 0);
            }
            else if(yIndex == 1) {
                hArrow->start->setCoords(0, plotHeight);
                hArrow->end->setCoords(AllWidth, plotHeight);
            }
            else {
                hArrow->start->setCoords(0, AllHeight);
                hArrow->end->setCoords(AllWidth, AllHeight);
            }
            bYImageOrAOI = true;
        }
        else {
            EllipseParams params = getEllipseParams(0);
            if(yIndex == 0) {
                preHArrowStartY = params.center.y() - params.minor/2;
                hArrow->start->setCoords(0, preHArrowStartY);
                hArrow->end->setCoords(AllWidth, preHArrowStartY);
            }
            else if(yIndex == 1) {
                preHArrowStartY = params.center.y();
                hArrow->start->setCoords(0, preHArrowStartY);
                hArrow->end->setCoords(AllWidth, preHArrowStartY);
            }
            else {
                preHArrowStartY = params.center.y() + params.minor/2;
                hArrow->start->setCoords(0, preHArrowStartY);
                hArrow->end->setCoords(AllWidth, preHArrowStartY);
            }
            bYImageOrAOI = true;
        }
    }
    //    _2DImagePlot->replot(QCustomPlot::rpQueuedReplot);
}

void LiveMode_2D_View::updateCoordsPos(bool isLeftOrTop, int index) {
    double plotWidth = 640;
    double plotHeight = 512;
    double AllWidth=1280;
    double AllHeight=1024;
    if(isLeftOrTop) {
        if(index == 0) {
            if(bXImageOrAOI) {
                vArrow->start->setCoords(0, 0);
                vArrow->end->setCoords(0, AllHeight);
            }
            else {
                EllipseParams params = getEllipseParams(0);
                prevArrowStartX = params.center.x() - params.major/2;
                vArrow->start->setCoords(prevArrowStartX, 0);
                vArrow->end->setCoords(prevArrowStartX, AllHeight);
            }
            xIndex = 0;
        }
        else if (index == 1) {
            if(bXImageOrAOI) {
                vArrow->start->setCoords(plotWidth, 0);
                vArrow->end->setCoords(plotWidth, AllHeight);
            }
            else {
                EllipseParams params = getEllipseParams(0);
                prevArrowStartX = params.center.x();
                vArrow->start->setCoords(prevArrowStartX, 0);
                vArrow->end->setCoords(prevArrowStartX, AllHeight);
            }
            xIndex = 1;
        }
        else {
            if(bXImageOrAOI) {
                vArrow->start->setCoords(AllWidth, 0);
                vArrow->end->setCoords(AllWidth, AllHeight);
            }
            else {
                EllipseParams params = getEllipseParams(0);
                prevArrowStartX = params.center.x() + params.major/2;
                vArrow->start->setCoords(prevArrowStartX, 0);
                vArrow->end->setCoords(prevArrowStartX, AllHeight);
            }
            xIndex = 2;
        }
    }
    else {
        if(index == 0) {
            if(bYImageOrAOI) {
                hArrow->start->setCoords(0, 0);
                hArrow->end->setCoords(AllWidth, 0);
            }
            else {
                EllipseParams params = getEllipseParams(0);
                preHArrowStartY = params.center.y() - params.minor/2;
                hArrow->start->setCoords(0, preHArrowStartY);
                hArrow->end->setCoords(AllWidth, preHArrowStartY);
            }
            yIndex = 0;
        }
        else if(index == 1) {
            if(bYImageOrAOI) {
                hArrow->start->setCoords(0, plotHeight);
                hArrow->end->setCoords(AllWidth, plotHeight);
            }
            else {
                EllipseParams params = getEllipseParams(0);
                preHArrowStartY = params.center.y();
                hArrow->start->setCoords(0, preHArrowStartY);
                hArrow->end->setCoords(AllWidth, preHArrowStartY);
            }
            yIndex = 1;
        }
        else {
            if(bYImageOrAOI) {

                hArrow->start->setCoords(0, AllHeight);
                hArrow->end->setCoords(AllWidth, AllHeight);
            }
            else {
                EllipseParams params = getEllipseParams(0);
                preHArrowStartY = params.center.y() + params.minor/2;
                hArrow->start->setCoords(0, preHArrowStartY);
                hArrow->end->setCoords(AllWidth, preHArrowStartY);
            }
            yIndex = 2;
        }
    }
}

LiveMode_2D_View::~LiveMode_2D_View() {
    if (m_lutWidget != nullptr) {
        delete m_lutWidget;
    }
    delete ui;
//    getFloatThreadThreadRunning.store(false, std::memory_order_release);
//    if(showFloatThread.joinable()) {
//        showFloatThread.join();
//    }
}

void LiveMode_2D_View::initCoordinateSystem(){
    QVector<qreal> dashes;
    dashes << 9 << 9;

    hArrow = new QCPItemLine(_2DImagePlot);
    hArrow->setHead(QCPLineEnding::esSpikeArrow);

    QPen h_pen(Qt::cyan, 1);
    h_pen.setDashPattern(dashes);
    hArrow->setPen(h_pen);

    vArrow = new QCPItemLine(_2DImagePlot);
    vArrow->setHead(QCPLineEnding::esSpikeArrow);

    QPen v_pen(Qt::cyan, 1);
    v_pen.setDashPattern(dashes);
    vArrow->setPen(v_pen);

    hArrow->setVisible(false);
    vArrow->setVisible(false);
}

void LiveMode_2D_View::set2DMapArea(){
    centerHLine = new QCPItemLine(_2DImagePlot);
    centerVLine = new QCPItemLine(_2DImagePlot);
    crossSectionLine = new QCPItemLine(_2DImagePlot);
    crossSectionText = new QCPItemText(_2DImagePlot);
    centerHLine->setLayer("crossLayer");
    centerVLine->setLayer("crossLayer");
    centerHLine->setVisible(false);
    centerVLine->setVisible(false);
    crossSectionLine->setLayer("crossLayer");
    crossSectionLine->setVisible(false);
    crossSectionLine->setPen(QPen(Qt::white, 2));
    crossSectionText->setText("Y = 0.00");
    crossSectionText->setColor(Qt::yellow);

    _2DImagePlot->setBackground(QColor(0, 0, 50));
    _2DImagePlot->setNoAntialiasingOnDrag(true);
    _2DImagePlot->setInteractions(QCP::iRangeDrag|QCP::iRangeZoom);

    _2DImagePlot->axisRect()->setupFullAxesBox(true);

    auto *marginGroup = new QCPMarginGroup(_2DImagePlot);
    _2DImagePlot->axisRect()->setMarginGroup(QCP::msBottom|QCP::msTop, marginGroup);
//    colorScale->setMarginGroup(QCP::msBottom|QCP::msTop, marginGroup);
    //_2DImagePlot->rescaleAxes();
    ui->_2DImageScrollArea->setWidget(_2DImagePlot);
    _2DImagePlot->xAxis->grid()->setVisible(false);
    _2DImagePlot->yAxis->grid()->setVisible(false);
    _2DImagePlot->axisRect()->setAutoMargins(QCP::msNone);
    _2DImagePlot->axisRect()->setMargins(QMargins(0, 0, 0, 0));

    // AOI Ellipse
    ellipse = new QCPCurve(_2DImagePlot->xAxis, _2DImagePlot->yAxis);
    QPen pen(Qt::DashLine);
    pen.setColor(Qt::white);
    ellipse->setPen(pen);
    ellipse->setLayer("crossLayer");
    // 创建主AOI标签
    createAOILabel(0, ellipse);
    // Fitting Ellipse
    fittingEllipse = new QCPCurve(_2DImagePlot->xAxis, _2DImagePlot->yAxis);
    QPen fittingPen(Qt::SolidLine);
    fittingPen.setColor(Qt::red);
    fittingEllipse->setPen(fittingPen);
    fittingEllipse->setLayer("crossLayer");

    // CrossSection Ellipse
    crossSectionCircle = new QCPItemEllipse(_2DImagePlot);
    QPen crossPen(Qt::SolidLine);
    crossPen.setColor(Qt::green);
    crossSectionCircle->setPen(crossPen);
    crossSectionCircle->setSelectable(true);
    QPen selectedCrossPen(Qt::SolidLine);
    selectedCrossPen.setColor(Qt::yellow);
    selectedCrossPen.setWidth(1);
    crossSectionCircle->setSelectedPen(selectedCrossPen);
    crossSectionCircle->setLayer("crossLayer");

//    coordinateLabel = new QCPItemText(_2DImagePlot);
//    coordinateLabel->setColor(Qt::red);
//    coordinateLabel->setFont(QFont("Arial", 12));
////    coordinateLabel->setPen(QPen(Qt::red));
//    coordinateLabel->setPositionAlignment(Qt::AlignTop | Qt::AlignHCenter);
//    coordinateLabel->position->setType(QCPItemPosition::ptPlotCoords);
//    coordinateLabel->setTextAlignment(Qt::AlignCenter);
//    coordinateLabel->setFont(QFont(font().family(), 12));  // 设置字体
//    coordinateLabel->setColor(Qt::white);  // 设置颜色
//    coordinateLabel->setBrush(QBrush(Qt::black));  // 背景色
//    coordinateLabel->setLayer("crossLayer");

//    _2DImagePlot->setInteractions(QCP::iRangeDrag | QCP::iRangeZoom); // 允许拖动和缩放
    _2DImagePlot->setInteractions( QCP::iRangeZoom); // 允许缩放
    setMouseTracking(true);
    // ellipses.emplace_back(ellipse);
    ellipses[0] = ellipse;
    imageItem = new QCPItemPixmap(_2DImagePlot);
    imageItem->setScaled(true, Qt::KeepAspectRatio);

    _2DImagePlot->xAxis->setTicks(false);
    _2DImagePlot->xAxis->setTickLabels(false);
    _2DImagePlot->yAxis->setTicks(false);
    _2DImagePlot->yAxis->setTickLabels(false);
    _2DImagePlot->yAxis->setRangeReversed(true);

    powerProfileEllipse = new QCPCurve(_2DImagePlot->xAxis, _2DImagePlot->yAxis);
    powerProfileEllipse->setVisible(false);
    QPen pen1;
    pen1.setColor(Qt::white);
    powerProfileEllipse->setPen(pen1);
//    powerProfileEllipse->setSelectable(true);
//    powerProfileEllipse->setSelectedPen(selectedPen);
    powerProfileEllipse->setLayer("crossLayer");
}

void LiveMode_2D_View::initEllipses(const double dPositionX_px, const double dPositionY_px, const double dMajor_px, const double dMinor_px) const {
    // 确保坐标轴范围已正确设置
    if (nSizeX > 0 && nSizeY > 0) {
        _2DImagePlot->xAxis->setRange(0, nSizeX);
        _2DImagePlot->yAxis->setRange(0, nSizeY);
        // 确保坐标轴比例正确
        _2DImagePlot->xAxis->setScaleRatio(_2DImagePlot->yAxis, 1.0);
    }

    // 更新主椭圆参数
    EllipseParams params;
    params.center = QPointF(dPositionX_px, dPositionY_px);
    params.major = dMajor_px;
    params.minor = dMinor_px;
    params.azimuthAngle = 0.0; // 初始化时角度为0

    const_cast<LiveMode_2D_View*>(this)->setEllipseParams(0, params);
    const_cast<LiveMode_2D_View*>(this)->updateEllipseCurve(ellipse, params.center, params.major, params.minor, params.azimuthAngle);
    _2DImagePlot->replot(QCustomPlot::rpQueuedReplot);
}

void LiveMode_2D_View::updateFittingEllipses(double dPositionX_px, double dPositionY_px, double dMajor_px, double dMinor_px, double angle) {
//    fittingEllipse->setVisible(true);
//    fittingEllipse->topLeft->setCoords(dPositionX_px - dMajor_px / 2, dPositionY_px - dMinor_px / 2);
//    fittingEllipse->bottomRight->setCoords(dPositionX_px + dMajor_px / 2, dPositionY_px + dMinor_px / 2);

//    double theta = angle * M_PI / 180.0;
//    QVector<double> xData, yData;
//    for (double t = 0.0; t < 2 * M_PI; t += 0.01) {
//        xData.append(dPositionX_px + dMajor_px * cos(t) * cos(theta) - dMinor_px * sin(t) * sin(theta));
//        yData.append(dPositionY_px + dMajor_px * cos(t) * sin(theta) + dMinor_px * sin(t) * cos(theta));
//    }
//    QCPGraph *graph = _2DImagePlot->addGraph();
//    graph->setData(xData, yData);
//    graph->setPen(QPen(Qt::black));
//    graph->setLineStyle(QCPGraph::lsLine);
//    graph->setBrush(Qt::NoBrush);
//    graph->setScatterStyle(QCPScatterStyle(QCPScatterStyle::ssCircle, 4));

    _2DImagePlot->replot(QCustomPlot::rpQueuedReplot);
}

void LiveMode_2D_View::setImageSize() const {
    // _2DImagePlot->setFixedSize(nSizeX, nSizeY);

    if (nSizeX > 0 && nSizeY > 0) {
        _2DImagePlot->xAxis->setRange(0, nSizeX);
        _2DImagePlot->yAxis->setRange(0, nSizeY);
        // 确保坐标轴比例正确
        _2DImagePlot->xAxis->setScaleRatio(_2DImagePlot->yAxis, 1.0);
    }
}

void LiveMode_2D_View::checkAuto(bool isChecked) {
    ui->cBox_Auto->setChecked(isChecked);
}

void LiveMode_2D_View::setCrossCenterPos(double xPos, double yPos) {
    crossCenter.setX(xPos);
    crossCenter.setY(yPos);
}

void LiveMode_2D_View::resizeEvent(QResizeEvent *event){
    QDockWidget::resizeEvent(event); // 调用基类的resizeEvent

    // if(!bFirst) {
    //     // 确保坐标轴范围正确
    //     if (nSizeX > 0 && nSizeY > 0) {
    //         _2DImagePlot->xAxis->setRange(0, nSizeX);
    //         _2DImagePlot->yAxis->setRange(0, nSizeY);
    //     }
    //     _2DImagePlot->xAxis->setScaleRatio(_2DImagePlot->yAxis, 1.0);
    //     _2DImagePlot->replot(QCustomPlot::rpQueuedReplot);
    //
    //     qDebug() << "resizeEvent - 窗口大小改变，重新设置坐标轴";
    //     qDebug() << "  图像大小: " << nSizeX << " x " << nSizeY;
    // }
    // bFirst = false;

    if (nSizeX > 0 && nSizeY > 0) {
        _2DImagePlot->xAxis->setScaleRatio(_2DImagePlot->yAxis, 1.0);
        _2DImagePlot->replot(QCustomPlot::rpQueuedReplot);
    }

    QTimer::singleShot(0, this,[this]() {

        m_lutWidget->updateLUTDisplay(ui->LUT_Widget);
    });
   // updateLUTDisplay();
}

void LiveMode_2D_View::btnMeasurement_Click() {
    QMenu *menu = new QMenu(this);

    // 定义菜单项和对应的索引
    QList<QPair<QString, int>> menuItems = {
        {"Background Correction", 0},
        {"Single Measurement", 1},
        {"Measure Stack", 2},
        {"Time Series", 3},
        {"Divergence", 4},
        {"Beam Quality", 5},
        {"Beam Line", 6},
        {"Beam Stability", 7},
        {"Pointing Stability", 8},
        {"Snap Shot", 9},
        {"Video Stream", 10}
    };

    for (const auto &item : menuItems) {
        QAction *action = menu->addAction(item.first);
        connect(action, &QAction::triggered, this, [this, index = item.second]() {
            emit startMeasurement(index);
        });
    }

    menu->exec(QCursor::pos());
    menu->deleteLater();
}

void LiveMode_2D_View::btnSnapshot_Click() {
    emit startSnapshot();
}

void LiveMode_2D_View::btnAOISelection_Click() {
    // 获取按钮的全局位置
    QPoint buttonPos = ui->btnAOISelection->mapToGlobal(QPoint(0, 0));
    
    // 计算菜单显示位置 - 在按钮右侧
    QPoint menuPos;
    menuPos.setX(buttonPos.x() + ui->btnAOISelection->width());
    menuPos.setY(buttonPos.y());
    
    // 在显示菜单前，确保菜单项的选中状态与存储的状态一致
    for (int i = 0; i < m_aoiActions.size() && i < m_aoiStates.size(); ++i) {
        m_aoiActions[i]->setChecked(m_aoiStates[i]);
    }
    
    // 显示菜单
    m_pAOIMenu->exec(menuPos);
}

void LiveMode_2D_View::btnBeamResults_Click() {
    emit showBeamResult();
//    if(LogManager::instance()) {
//        qDebug() << LogManager::instance();
//        LogManager::instance()->logMessage(QtDebugMsg, "LiveMode_2D_View");
//    }
}

void LiveMode_2D_View::btnCross_Section_Click() {
    crossCenter.setX(nSizeX / 2);
    crossCenter.setY(nSizeY / 2);
    emit showCrossSection();
}

void LiveMode_2D_View::btnCentroid_Click() {
    emit showCentroidDistances();
}

void LiveMode_2D_View::btnPower_Profile_Click(){
    emit showPowerProfile();
}

void LiveMode_2D_View::btnHistogram_Click() {
    emit showHistogram();
}

void LiveMode_2D_View::btn_BeamProfiler_Dynamic_Click() {
    emit showBeamProfilerDynamic();
}

void LiveMode_2D_View::btn3D_View_Click() {
    emit show3D_View();
}

void LiveMode_2D_View::paintCenterPos(const double x_center, const double y_center) const {
    centerHLine->start->setCoords(x_center - 20, y_center);
    centerHLine->end->setCoords(x_center + 20, y_center);
    centerHLine->setPen(QPen(Qt::red));

    centerVLine->start->setCoords(x_center, y_center - 20);
    centerVLine->end->setCoords(x_center, y_center + 20);
    centerVLine->setPen(QPen(Qt::red));

    centerHLine->setVisible(true);
    centerVLine->setVisible(true);
    _2DImagePlot->replot(QCustomPlot::rpQueuedReplot);
}

void LiveMode_2D_View::hideCenterPos() const {
    centerHLine->setVisible(false);
    centerVLine->setVisible(false);
}

void LiveMode_2D_View::hidePowerProfileEllipse() {
    powerProfileEllipse->setVisible(false);
}

void LiveMode_2D_View::paintPowerProfileEllipse(double x_center, double y_center, double major, double minor) {
    powerProfileEllipse->setVisible(true);
    updateEllipseCurve(powerProfileEllipse, QPointF(x_center, y_center), major, minor, 0.0);
    _2DImagePlot->replot(QCustomPlot::rpQueuedReplot);
}

void LiveMode_2D_View::paintXCrossSection(const double y_pos) {
    crossSectionLine->start->setCoords(0, y_pos);
    crossSectionLine->end->setCoords(nSizeX, y_pos);
    crossSectionText->position->setType(QCPItemPosition::ptPlotCoords);
    crossSectionText->position->setCoords(nSizeY / 2, 100);
    setLineCircleVisible(true);
    _2DImagePlot->replot(QCustomPlot::rpQueuedReplot);
}

void LiveMode_2D_View::paintYCrossSection(double x_pos) {
    crossSectionLine->start->setCoords(x_pos, 0);
    crossSectionLine->end->setCoords(x_pos, nSizeY);
    setLineCircleVisible(true);
    _2DImagePlot->replot(QCustomPlot::rpQueuedReplot);
}

void LiveMode_2D_View::paintRadialSection(double y_pos) {
    crossSectionLine->start->setCoords(0, y_pos);
    crossSectionLine->end->setCoords(nSizeX, y_pos);
    setLineCircleVisible(true);
    _2DImagePlot->replot(QCustomPlot::rpQueuedReplot);
}

// 参数：中心点、夹角（弧度制）、矩形边界（x_min, x_max, y_min, y_max）
void LiveMode_2D_View::drawClippedLine(double x_center, double y_center, double angle,
                     double x_min, double x_max, double y_min, double y_max) {
    // 计算斜率和截距
    double m = tan(angle);
    double c = y_center - m * x_center;

    // 存储交点
    QVector<QPointF> intersectionPoints;

    // 计算与上下边界的交点
    if (m != 0) { // 避免垂直直线导致除零
        double x1 = (y_min - c) / m; // 与 y = y_min 的交点
        if (x1 >= x_min && x1 <= x_max)
            intersectionPoints.append(QPointF(x1, y_min));

        double x2 = (y_max - c) / m; // 与 y = y_max 的交点
        if (x2 >= x_min && x2 <= x_max)
            intersectionPoints.append(QPointF(x2, y_max));
    }

    // 计算与左右边界的交点
    double y1 = m * x_min + c; // 与 x = x_min 的交点
    if (y1 >= y_min && y1 <= y_max)
        intersectionPoints.append(QPointF(x_min, y1));

    double y2 = m * x_max + c; // 与 x = x_max 的交点
    if (y2 >= y_min && y2 <= y_max)
        intersectionPoints.append(QPointF(x_max, y2));

    // 检查交点数是否足够绘制直线
    if (intersectionPoints.size() >= 2) {
        // 按距离中心点的远近排序
        std::sort(intersectionPoints.begin(), intersectionPoints.end(),
                  [x_center, y_center](const QPointF &a, const QPointF &b) {
                      double da = qPow(a.x() - x_center, 2) + qPow(a.y() - y_center, 2);
                      double db = qPow(b.x() - x_center, 2) + qPow(b.y() - y_center, 2);
                      return da < db;
                  });

        // 选择最近的两个交点作为直线端点
        QPointF start = intersectionPoints[0];
        QPointF end = intersectionPoints[1];

        crossSectionLine->start->setCoords(start.x(), start.y());
        crossSectionLine->end->setCoords(end.x(), end.y());
        crossSectionLine->setPen(QPen(Qt::blue, 2)); // 设置线条颜色和宽度

        _2DImagePlot->replot(QCustomPlot::rpQueuedReplot);
    }
}

void LiveMode_2D_View::paintArbitrarySection(double dX1, double dY1, double dX2, double dY2) {
    crossSectionLine->start->setCoords(dX1, dY1);
    crossSectionLine->end->setCoords(dX2, dY2);
    setLineCircleVisible(true);
    _2DImagePlot->replot(QCustomPlot::rpQueuedReplot);
}

void LiveMode_2D_View::paintCrossCircle(double dX, double dY, double dRadius) {
    setLineCircleVisible(false);
    crossSectionCircle->topLeft->setCoords(dX - dRadius, dY - dRadius);
    crossSectionCircle->bottomRight->setCoords(dX + dRadius, dY + dRadius);
    _2DImagePlot->replot(QCustomPlot::rpQueuedReplot);
}

void LiveMode_2D_View::receiveMessage(const std::shared_ptr<LiveModeFloatData<std::vector<float>>>& data) {
//    std::unique_lock<std::mutex> lock(mutex);
//    _vecData = data->floatData();
}

void LiveMode_2D_View::processCCDImageData(const std::shared_ptr<QPixmap>& pixmap) const {
//    const QPixmap pixmap = QPixmap::fromImage(image);
    if(!pixmap) return;
    imageItem->setPixmap(*pixmap);
    static bool coordsSet = false;
    if (!coordsSet) {
        imageItem->topLeft->setCoords(0, 0);
        imageItem->bottomRight->setCoords(nSizeX, nSizeY);
        coordsSet = true;
    }
    _2DImagePlot->replot(QCustomPlot::rpQueuedReplot);
}

void LiveMode_2D_View::processFloatData(std::shared_ptr<std::vector<float>> &vecData) {
//    std::lock_guard<std::mutex> lock(mutex);
//    _vecData = vecData;
    if(!vecData) return;
    _vecData = *vecData;
}

float LiveMode_2D_View::getDataAt(const int x, const int y) {
    std::unique_lock<std::mutex> lock(mutex);
    auto a = _vecData[x * nSizeX + y];
    return a;
}

void LiveMode_2D_View::setLineCircleVisible(bool showLine) {
    crossSectionLine->setSelectable(showLine);
    crossSectionLine->setVisible(showLine);
    crossSectionCircle->setSelectable(!showLine);
    crossSectionCircle->setVisible(!showLine);
}

void LiveMode_2D_View::setWindowTitleName(const QString& name) {
    setWindowTitle("LiveMode:2D-View -" + name);
}

void LiveMode_2D_View::closeEvent(QCloseEvent *event) {
    emit closeLiveModeWindows();
}
//初始化所有AOI的启用和可见性状态
void LiveMode_2D_View::initAOIStates() {
    // 初始化AOI状态数组，默认只有AOI1是选中的
    m_aoiStates.resize(MAX_AOIITEM, false);
    m_aoiStates[0] = true; // 只有AOI1是选中的
    int size =m_aoiActions.size();
    // 根据初始状态设置菜单项的选中状态
    for (int i = 1; i < size; ++i) {
        m_aoiActions[i]->setChecked(m_aoiStates[i]);
        if (i < ellipses.size() && ellipses[i] != nullptr) {
            ellipses[i]->setVisible(m_aoiStates[i]);
        }
    }
}

//创建AOI的标签和位置
void LiveMode_2D_View::createAOILabel(int index, QCPCurve* ellipseCurve) {
    // 检查是否已存在标签，如果存在则直接更新而不是重新创建
    QCPItemText* aoiLabel = nullptr;
    if (index < aoiLabels.size() && aoiLabels[index] != nullptr) {
        aoiLabel = aoiLabels[index];
    } else {
        aoiLabel = new QCPItemText(_2DImagePlot);
        aoiLabels[index] = aoiLabel;
    }

    // 设置标签属性
    aoiLabel->setText("AOI" + QString::number(index+1));
    aoiLabel->setColor(Qt::white);
    aoiLabel->setFont(QFont(font().family(), 10));

    // 获取椭圆参数
    EllipseParams params = getEllipseParams(index);

    // 计算标签位置 - 在椭圆边缘的随机位置
    double angle = (QRandomGenerator::global()->bounded(360)) * M_PI / 180.0;
    double radiusX = params.major / 2;
    double radiusY = params.minor / 2;
    double centerX = params.center.x();
    double centerY = params.center.y();

    // 存储标签相对于椭圆中心的角度，用于后续更新
    aoiLabel->setProperty("labelAngle", angle);

    double x = centerX + radiusX * cos(angle);
    double y = centerY + radiusY * sin(angle);
    aoiLabel->position->setCoords(x, y);
    aoiLabel->setLayer("crossLayer");
    aoiLabel->setVisible(ellipseCurve->visible());
}
//更新AOI的标签和位置
void LiveMode_2D_View::updateAOILabels() {
    for (int i = 0; i < ellipses.size(); ++i) {
        if (ellipses[i] && ellipses[i]->visible() && i < aoiLabels.size() && aoiLabels[i]) {
            // 获取椭圆参数
            EllipseParams params = getEllipseParams(i);
            double centerX = params.center.x();
            double centerY = params.center.y();
            double radiusX = params.major / 2;
            double radiusY = params.minor / 2;

            // 获取存储的标签角度，如果没有则计算一个
            bool ok;
            double angle = aoiLabels[i]->property("labelAngle").toDouble(&ok);
            if (!ok) {
                // 如果没有存储角度，计算当前角度并存储
                QPointF labelPos = aoiLabels[i]->position->coords();
                double dx = labelPos.x() - centerX;
                double dy = labelPos.y() - centerY;
                angle = atan2(dy, dx);
                aoiLabels[i]->setProperty("labelAngle", angle);
            }

            // 使用固定角度计算新位置（考虑旋转）
            double azimuthRad = params.azimuthAngle * M_PI / 180.0;
            double cosAzimuth = cos(azimuthRad);
            double sinAzimuth = sin(azimuthRad);

            // 在椭圆本地坐标系中计算位置
            double localX = radiusX * cos(angle);
            double localY = radiusY * sin(angle);

            // 应用旋转变换
            double rotatedX = localX * cosAzimuth - localY * sinAzimuth;
            double rotatedY = localX * sinAzimuth + localY * cosAzimuth;

            // 转换到全局坐标系
            double x = centerX + rotatedX;
            double y = centerY + rotatedY;
            aoiLabels[i]->position->setCoords(x, y);
        }
    }
}
//根据是否存在创建一个椭圆或者显示该椭圆
QCPCurve* LiveMode_2D_View::createOrShowAOIEllipse(int index, bool createIfNotExists) {
    // 如果椭圆已存在，直接显示它
    if (index < ellipses.size() && ellipses[index] != nullptr) {
        ellipses[index]->setVisible(true);
        // 更新标签可见性
        if (index < aoiLabels.size() && aoiLabels[index] != nullptr) {
            aoiLabels[index]->setVisible(true);
        } else {
            // 如果标签不存在则创建
            createAOILabel(index, ellipses[index]);
        }
        emit Show_Or_Hide_Aoi(index, true);
        m_settings->updateEnabledAoi(index,true);
        return ellipses[index];
    }

    // 如果椭圆不存在且需要创建
     if (createIfNotExists) {
         QCPCurve *newEllipse = new QCPCurve(_2DImagePlot->xAxis, _2DImagePlot->yAxis);
         double offsetX = 30 * (index % 5);  // 水平偏移
         double offsetY = 30 * (index / 5);  // 垂直偏移

         // 基于主AOI的参数创建新的AOI
         EllipseParams mainParams = getEllipseParams(0);
         EllipseParams newParams;
         newParams.center = QPointF(mainParams.center.x() + offsetX, mainParams.center.y() + offsetY);
         newParams.major = mainParams.major;
         newParams.minor = mainParams.minor;
         newParams.azimuthAngle = mainParams.azimuthAngle;

         // 设置样式
         QPen pen(Qt::DashLine);
         QColor color=m_settings->getColorForIndex(index+1);
         pen.setColor(color);
         newEllipse->setPen(pen);
         newEllipse->setLayer("crossLayer");

         // 存储椭圆和参数
         ellipses[index] = newEllipse;
         setEllipseParams(index, newParams);
         updateEllipseCurve(newEllipse, newParams.center, newParams.major, newParams.minor, newParams.azimuthAngle);

         // 创建对应的标签
         createAOILabel(index, newEllipse);
         emit Show_Or_Hide_Aoi(index, true);
         m_settings->updateEnabledAoi(index,true);
         return newEllipse;
    }
    emit Show_Or_Hide_Aoi(index, true);
    m_settings->updateEnabledAoi(index,true);
    return ellipses[index];;

}
//更改和存储该AOI椭圆的可见性
void LiveMode_2D_View::updateAOIVisibility(int index, bool show) {
    // 更新AOI状态
    m_aoiStates[index] = show;
    // 更新菜单项选中状态
    if (index < m_aoiActions.size()) {
        m_aoiActions[index]->setChecked(show);
    }
    // 更新椭圆和标签的可见性
    if (show) {
        createOrShowAOIEllipse(index);
    }
    else if (index < ellipses.size() && ellipses[index] != nullptr) {
        ellipses[index]->setVisible(false);
        // 更新标签可见性
        if (index < aoiLabels.size() && aoiLabels[index] != nullptr) {
            aoiLabels[index]->setVisible(false);
        }
        emit Show_Or_Hide_Aoi(index, false);
        m_settings->updateEnabledAoi(index,false);
    }
}
//多AOI按钮点击触发事件
void LiveMode_2D_View::onAOIActionTriggered(QAction *action) {
    int index = action->data().toInt();
    // 如果要取消选中当前AOI
    if (m_aoiStates[index]) {
        // 计算当前选中的AOI数量
        int selectedCount = 0;
        for (bool state : m_aoiStates) {
            if (state) selectedCount++;
        }
        // 如果只有一个AOI被选中且是当前AOI，则不允许取消选中
        if (selectedCount == 1) {
            qDebug() << "不能取消唯一选中的AOI";
            return;
        }
        // 如果当前AOI是主AOI，需要将主AOI转移到另一个选中的AOI
        if (index == m_mainAOIIndex) {
            // 寻找第一个选中的AOI作为新的主AOI
            int newMainIndex = -1;
            for (int i = 0; i < m_aoiStates.size(); ++i) {
                if (m_aoiStates[i] && i != index) {
                    newMainIndex = i;
                    break;
                }
            }
            // 如果找到了新的主AOI，设置它
            if (newMainIndex != -1) {
                setMainAOI(newMainIndex);
            }
        }
        // 更新AOI可见性
        updateAOIVisibility(index, false);
        m_settings->updateEnabledAoi(index,false);
        emit Show_Or_Hide_Aoi(index, false);
    }
    else {
        // 更新AOI可见性
        updateAOIVisibility(index, true);
        // 设置为主AOI
        setMainAOI(index);
    }
    // 更新菜单显示
    m_pAOIMenu->update();
    // 重绘图表
    _2DImagePlot->replot(QCustomPlot::rpQueuedReplot);
}

void LiveMode_2D_View::handleShowOrHideAoi(int index, bool show) {
    // 检查索引是否有效
    if (index < 0 || index >= m_aoiStates.size()-1) {
        qDebug() << "无效的AOI索引:" << index;
        return;
    }
    
    // 如果尝试隐藏AOI
    if (!show) {
        // 计算当前启用的AOI数量
        int enabledCount = 0;
        for (bool state : m_aoiStates) {
            if (state) enabledCount++;
        }
        
        // 如果这是最后一个启用的AOI，阻止隐藏操作
        if (enabledCount <= 1 && m_aoiStates[index]) {
            m_settings->updateEnabledAoi(index,true);
            qDebug() << "不能隐藏最后一个AOI";
            return;
        }
        
        // 如果隐藏的是当前主AOI，需要找到新的主AOI
        if (index == m_mainAOIIndex && m_aoiStates[index]) {
            // 寻找第一个启用的AOI作为新的主AOI
            int newMainIndex = -1;
            for (int i = 0; i < m_aoiStates.size(); ++i) {
                if (i != index && m_aoiStates[i]) {
                    newMainIndex = i;
                    break;
                }
            }
            
            // 如果找到了新的主AOI，设置它
            if (newMainIndex != -1) {
                setMainAOI(newMainIndex);
            }
        }
    }
    
    // 使用通用的更新可见性函数
    updateAOIVisibility(index, show);
    
    // 重绘图表
    _2DImagePlot->replot(QCustomPlot::rpQueuedReplot);
}

void LiveMode_2D_View::handleMainAOIChanged(int index) {
    // 检查索引是否有效
    if (index < 0 || index > m_aoiStates.size()-1) {
        qDebug() << "无效的主AOI索引:" << index;
        return;
    }
    // 确保该AOI是启用的
    if (!m_aoiStates[index]) {
        m_aoiStates[index] = true;
        // 更新菜单项选中状态
        if (index < m_aoiActions.size()) {
            m_aoiActions[index]->setChecked(true);
        }
        // 使用已有函数创建或显示椭圆
        createOrShowAOIEllipse(index);
    }
    // 设置为主AOI
    setMainAOI(index);
}

void LiveMode_2D_View::mousePressEvent(QMouseEvent *event) {
    QDockWidget::mousePressEvent(event);
    this->raise();
    this->activateWindow();
    emit Live2DModeViewClicked();
}

void LiveMode_2D_View::setMainAOI(int index) {
    // 检查索引是否有效
    if (index < 0 || index >= m_aoiActions.size()) {
        return; // 无效索引，直接返回
    }
    // 如果新索引与当前主AOI索引相同，则无需操作
    if (index == m_mainAOIIndex) {
        return;
    }
    // 清除旧主AOI样式
    QAction* oldMain = m_aoiActions[m_mainAOIIndex];
    QFont normalFont = oldMain->font();
    normalFont.setBold(false);
    oldMain->setFont(normalFont);
    oldMain->setText(oldMain->text().replace(" ★", "")); // 移除标记
    // 设置新主AOI样式
    QAction* newMain = m_aoiActions[index];
    QFont boldFont = newMain->font();
    boldFont.setBold(true);
    newMain->setFont(boldFont);
    newMain->setText(newMain->text() + " ★"); // 添加主标记
    // 确保主AOI被选中（即使此前未选）
    newMain->setChecked(true);
    m_aoiStates[index] = true; // 更新状态数组
    // 更新标签颜色与椭圆一致
    if (index < ellipses.size() && ellipses[index] != nullptr &&
        index < aoiLabels.size() && aoiLabels[index] != nullptr) {
        QPen pen = ellipses[index]->pen();
        aoiLabels[index]->setColor(pen.color());
        // 更新标签位置
        updateAOILabels();
        }
    // 更新主AOI索引
    m_mainAOIIndex = index;
    // 同步更新设置窗口中的UI状态
    if (m_settings) {
        m_settings->updateMainAOIUI(index);
    }
    emit mainAOIChanged(index);
}

// 基于Model数据更新AOI椭圆（直接使用像素坐标）
void LiveMode_2D_View::updateAOIEllipseFromModel(const AOI& aoiData) {
    if (!ellipse) return;

    if (bFirstAOIUpdate) {

        if (nSizeX > 0 && nSizeY > 0) {
            _2DImagePlot->xAxis->setRange(0, nSizeX);
            _2DImagePlot->yAxis->setRange(0, nSizeY);
            _2DImagePlot->xAxis->setScaleRatio(_2DImagePlot->yAxis, 1.0);
        }

        bFirstAOIUpdate = false;
    }

    // AOI数据已经是像素单位，直接使用
    double centerX = aoiData.dPositionX_px;
    double centerY = aoiData.dPositionY_px;
    double major = aoiData.dMajor_px;
    double minor = aoiData.dMinor_px;
    double azimuthAngle = aoiData.dAzimuthAngle_px;

    // 更新主椭圆参数
    EllipseParams params;
    params.center = QPointF(centerX, centerY);
    params.major = major;
    params.minor = minor;
    params.azimuthAngle = azimuthAngle;

    setEllipseParams(0, params);
    updateEllipseCurve(ellipse, params.center, params.major, params.minor, params.azimuthAngle);

    // 更新椭圆的可见性状态
    if (aoiData.bActive && m_aoiStates.size() > 0 && m_aoiStates[0]) {
        ellipse->setVisible(true);
    }

    // 更新标签位置
    updateAOILabels();

    // 重绘图表
    _2DImagePlot->replot(QCustomPlot::rpQueuedReplot);

}

// 更新椭圆曲线
void LiveMode_2D_View::updateEllipseCurve(QCPCurve *curve, const QPointF &center, double major, double minor, double azimuthAngle) {
    if (!curve) return;

    const int numPoints = 100; // 椭圆上的点数
    QVector<double> xData, yData;
    xData.reserve(numPoints + 1);
    yData.reserve(numPoints + 1);

    // 将角度转换为弧度，注意QCustomPlot的坐标系可能需要调整角度方向
    double theta = azimuthAngle * M_PI / 180.0; // 使用负角度，因为QCustomPlot的Y轴通常是反向的
    double cosTheta = cos(theta);
    double sinTheta = sin(theta);

    // 半轴长度
    double a = major / 2.0;  // 长半轴
    double b = minor / 2.0;  // 短半轴

    // 生成椭圆上的点
    for (int i = 0; i <= numPoints; ++i) {
        double t = 2.0 * M_PI * i / numPoints;

        // 椭圆上的标准点（未旋转）
        double x_std = a * cos(t);
        double y_std = b * sin(t);

        // 应用旋转变换
        double x_rot = x_std * cosTheta - y_std * sinTheta;
        double y_rot = x_std * sinTheta + y_std * cosTheta;

        // 平移到中心位置
        xData.append(center.x() + x_rot);
        yData.append(center.y() + y_rot);
    }

    curve->setData(xData, yData);
}

// 计算点到椭圆曲线边界的距离
double LiveMode_2D_View::calculateDistanceToCurveBoundary(QCPCurve *ellipseCurve, const QPointF &mousePos,
                                                          const QPointF &center, double major, double minor, double azimuthAngle) {
    if (!ellipseCurve) return std::numeric_limits<double>::max();

    // 将鼠标位置转换到椭圆坐标系，保持与绘制时一致的角度处理
    double theta = -azimuthAngle * M_PI / 180.0; // 与绘制时保持一致的逆旋转
    double cosTheta = cos(theta);
    double sinTheta = sin(theta);

    // 将鼠标坐标转换到椭圆的本地坐标系
    double dx = mousePos.x() - center.x();
    double dy = mousePos.y() - center.y();

    // 逆旋转变换
    double x_local = dx * cosTheta - dy * sinTheta;
    double y_local = dx * sinTheta + dy * cosTheta;

    // 计算椭圆上最近点的参数t
    double a = major / 2.0;
    double b = minor / 2.0;

    if (std::abs(a) < 1e-6 || std::abs(b) < 1e-6) {
        return std::numeric_limits<double>::max();
    }

    // 使用更精确的方法找到椭圆上最近的点
    double minDistance = std::numeric_limits<double>::max();

    for (int i = 0; i < 360; i += 2) { // 每2度检查一次，提高精度
        double t = i * M_PI / 180.0;
        double x_ellipse = a * cos(t);
        double y_ellipse = b * sin(t);

        double dist = std::hypot(x_local - x_ellipse, y_local - y_ellipse);
        if (dist < minDistance) {
            minDistance = dist;
        }
    }

    return minDistance;
}
// 获取椭圆中心点
QPointF LiveMode_2D_View::getEllipseCenter(int index) const {
    if (index >= 0 && index < ellipseParams.size()) {
        return ellipseParams[index].center;
    }
    return QPointF(0, 0);
}

// 获取椭圆参数
LiveMode_2D_View::EllipseParams LiveMode_2D_View::getEllipseParams(int index) const {
    if (index >= 0 && index < ellipseParams.size()) {
        return ellipseParams[index];
    }
    return EllipseParams();
}

// 设置椭圆参数
void LiveMode_2D_View::setEllipseParams(int index, const EllipseParams &params) {
    if (index >= 0 && index < ellipseParams.size()) {
        ellipseParams[index] = params;
    }
}

Qt::CursorShape LiveMode_2D_View::getCursorShapeForPosition(const QPointF &mousePos, const EllipseParams &params) const {
    // 坐标变换到椭圆本地坐标系
    double theta = -params.azimuthAngle * M_PI / 180.0;
    double cosTheta = cos(theta);
    double sinTheta = sin(theta);

    double dx = mousePos.x() - params.center.x();
    double dy = mousePos.y() - params.center.y();

    double x_local = dx * cosTheta - dy * sinTheta;
    double y_local = dx * sinTheta + dy * cosTheta;

    double a = params.major / 2.0;
    double b = params.minor / 2.0;

    if (a > 0 && b > 0) {
        // 计算椭圆参数角
        double t = atan2(a * y_local, b * x_local);

        // 计算局部法线方向（调整方向垂直于切线）
        double normalX = b * cos(t);
        double normalY = a * sin(t);

        // 计算法线角度（相对于水平方向）
        double normalAngle = atan2(normalY, normalX);

        // 将角度转换到0-2π范围
        if (normalAngle < 0) normalAngle += 2 * M_PI;


        if (normalAngle >= 15*M_PI/8 || normalAngle < M_PI/8) {
            return Qt::SizeHorCursor;        // 右 →
        } else if (normalAngle >= M_PI/8 && normalAngle < 3*M_PI/8) {
            return Qt::SizeBDiagCursor;      // 右上 ↗
        } else if (normalAngle >= 3*M_PI/8 && normalAngle < 5*M_PI/8) {
            return Qt::SizeVerCursor;        // 上 ↑
        } else if (normalAngle >= 5*M_PI/8 && normalAngle < 7*M_PI/8) {
            return Qt::SizeFDiagCursor;      // 左上 ↖
        } else if (normalAngle >= 7*M_PI/8 && normalAngle < 9*M_PI/8) {
            return Qt::SizeHorCursor;        // 左 ←
        } else if (normalAngle >= 9*M_PI/8 && normalAngle < 11*M_PI/8) {
            return Qt::SizeBDiagCursor;      // 左下 ↙
        } else if (normalAngle >= 11*M_PI/8 && normalAngle < 13*M_PI/8) {
            return Qt::SizeVerCursor;        // 下 ↓
        } else { // 13*M_PI/8 到 15*M_PI/8
            return Qt::SizeFDiagCursor;      // 右下 ↘
        }
    }

    return Qt::ArrowCursor;
}